package com.hskn.hss.module.tlequip.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.exception.ExcelReaderDataException;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.equiptype.entity.TlEquiptype;
import com.hskn.hss.module.equiptype.mapper.TlEquiptypeMapper;
import com.hskn.hss.module.tlchannel.entity.TlChannel;
import com.hskn.hss.module.tlchannel.mapper.TlChannelMapper;
import com.hskn.hss.module.tlequip.entity.TlEquip;
import com.hskn.hss.module.tlequip.mapper.TlEquipMapper;
import com.hskn.hss.module.tlequip.service.ITlEquipService;
import com.hskn.hss.module.tlequip.vo.TlEquipExcelOutVO;
import com.hskn.hss.module.tlequipbind.entity.TlEquipBind;
import com.hskn.hss.module.tlequipbind.mapper.TlEquipBindMapper;
import com.hskn.hss.module.tlequipbind.service.impl.TlEquipBindServiceImpl;
import com.hskn.hss.module.userdepart.entity.SysUserDepart;
import com.hskn.hss.module.userdepart.mapper.SysUserDepartMapper;
import com.hskn.hss.utils.AttributeUtils;
import com.hskn.hss.utils.GroupingByUtils;
import com.hskn.hss.utils.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-11
 */
@Service
public class TlEquipServiceImpl extends ServiceImpl<TlEquipMapper, TlEquip> implements ITlEquipService {

    @Resource
    TlEquipMapper tlEquipMapper;
    @Resource
    SysUserDepartMapper sysUserDepartMapper;
    @Resource
    TlEquiptypeMapper tlEquiptypeMapper;
    @Resource
    TlChannelMapper tlChannelMapper;
    @Resource
    TlEquipBindMapper tlEquipBindMapper;
    @Autowired
    TlEquipBindServiceImpl tlEquipBindService;
    @Override
    public AjaxResult insert(TlEquip tlEquip) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserDepart::getUserid, uid);
        String deptid = sysUserDepartMapper.selectOne(queryWrapper).getDepid();

        tlEquip.setCreateby(uid);
        tlEquip.setCreatetime(new Date());
        tlEquip.setDeptid(deptid);
        tlEquip.setStatus("1");
        tlEquip.setOnlinestatus("1");
        int i = tlEquipMapper.insert(tlEquip);
        boolean flag = i > 0 ? true : false;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public AjaxResult update(JSONObject params) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        TlEquip tlEquip = params.getObject("data", TlEquip.class);
        tlEquip.setUpdateby(uid);
        tlEquip.setUpdatetime(new Date());
        int i = tlEquipMapper.updateById(tlEquip);
        boolean flag = i > 0 ? true : false;
        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class}) //添加事务
    public AjaxResult updatebyids(TlEquip tlEquip) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        String ids = tlEquip.getIds();
        String[] idArray = ids.split(",");
        tlEquip.setUpdateby(uid);
        tlEquip.setUpdatetime(new Date());
        boolean a = false;
        String str = "";
        List<TlEquip> tlEquips = tlEquipMapper.selectBatchIds(Arrays.asList(idArray));
        for (TlEquip tl : tlEquips){
            if(!tlEquip.getStatus().equals(tl.getStatus()) && StringUtils.isNotEmpty(tl.getBindobjid())){
                 str = str +"请解绑后禁用:设备编号："+tl.getEquipcode()+"，已绑定对象："+tl.getBindobjname()+"##";
                a = true ;

            }
        }
        if(a == true){
            return AjaxResult.fail(str);
        }else{
            UpdateWrapper<TlEquip> tlEquipUpdateWrapper = new UpdateWrapper<>();
            tlEquipUpdateWrapper.lambda().in(TlEquip::getId, idArray);
            tlEquipMapper.update(tlEquip,tlEquipUpdateWrapper);

            //设备绑定信息更新
            QueryWrapper<TlEquipBind> tlEquipQueryWrapper = new QueryWrapper<>();
            tlEquipQueryWrapper.lambda().in(TlEquipBind::getEquipid,idArray);
            List<TlEquipBind> tlEquipBindList = tlEquipBindMapper.selectList(tlEquipQueryWrapper);


            List<TlEquip> tlEquip2 = tlEquipMapper.selectBatchIds(Arrays.asList(idArray));

            QueryWrapper<TlEquiptype> equiptypeQueryWrapper = new QueryWrapper<>();
            List<TlEquiptype> tlEquiptypeList = tlEquiptypeMapper.selectList(equiptypeQueryWrapper);

            Map<String,List<TlEquiptype>> map = tlEquiptypeList.stream().collect(Collectors.groupingBy(TlEquiptype::getId));


            if(CollectionUtils.isNotEmpty(tlEquipBindList)){
                for (TlEquipBind tlEquipBind : tlEquipBindList) {
                    for (TlEquip equip : tlEquip2) {
                       if(equip.getId().equals(tlEquipBind.getEquipid())){
                           String equipType = Objects.isNull(map.get(equip.getEquiptypeid()).get(0).getEquipname()) ? "" : map.get(equip.getEquiptypeid()).get(0).getEquipname();
                           tlEquipBind.setEquiptype(equip.getEquiptypeid());
                           tlEquipBind.setEquipcode(equip.getEquipcode());
                           tlEquipBind.setEquiptypename(equipType + "(" +equip.getEquipcode() + ")");
                       }
                    }
                }
                tlEquipBindService.updateBatchById(tlEquipBindList);
            }
            return AjaxResult.success("操作成功");
        }
    }

    @Override
    public AjaxResult deletebyid(JSONObject params) throws HssException {
        String id = params.getString("id");
        tlEquipMapper.deleteById(id);
        return AjaxResult.success("操作成功");
    }
    @Override
    public AjaxResult deletebatchbyid(TlEquip tlEquip) throws HssException {
        boolean a = false;
        String ids = tlEquip.getIds();
        String[] idArray = ids.split(",");
        String str = "";
        List<TlEquip> tlEquips = tlEquipMapper.selectBatchIds(Arrays.asList(idArray));
            for (TlEquip tl : tlEquips){
                if(StringUtils.isNotEmpty(tl.getBindobjid())){
                    str = str + "有设备已经被绑定，请解绑后删除:设备编号："+tl.getEquipcode()+"，已绑定对象："+tl.getBindobjname()+"##";
                    a = true ;
                }
            }
            if(a == true){
                return AjaxResult.fail(str);
            }else{
                tlEquipMapper.deleteBatchIds(Arrays.asList(idArray));
                return AjaxResult.success("操作成功");
            }

    }
    @Override
    public TlEquip getDetail(JSONObject params) throws HssException {
        String id = params.getString("id");
        TlEquip tlEquip = tlEquipMapper.selectById(id);
        return tlEquip;
    }

    //    @Override
//    public TlEquip getDetail(JSONObject params)throws HssException {
//        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
//        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
//        Map<String , Object> map = new HashMap();
//        map.put("id" , params.getString("id"));
//        Page<TlEquip> listPage = new Page<>(page, size, true);
//        IPage<TlEquip> iPage = tlEquipMapper.listEquip(listPage, map);
//        TlEquip tlEquip = iPage.getRecords().get(0);
//        return tlEquip;
//    }
    @Override
    public List getSelectList(JSONObject params) {

        Map<String, Object> map = new HashMap();
        map.put("equipcode", params.getString("equipcode"));
        map.put("equiptypeid", params.getString("equiptypeid"));
        map.put("equipmodelid", params.getString("equipmodelid"));
        map.put("bindstatus", params.getString("bindstatus"));

        List resultList = tlEquipMapper.getSelectList(map);
        return resultList;
    }


    @Override
    @DataScope(deptAlias = "binddeptid", userAlias = "createby, updateby")
    public JSONObject getList(BaseEntity entity, JSONObject params) throws HssException {
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        JSONObject json = new JSONObject();
        Map<String, Object> map = new HashMap();
        map.put("equipcode", params.getString("equipcode"));
        map.put("equipname", params.getString("equipname"));
        map.put("bindobjid", params.getString("bindobjid"));
        map.put("equiptypeid", params.getString("equiptypeid"));
        map.put("communicationcode", params.getString("communicationcode"));
        map.put("bindstatus", params.getString("bindstatus"));
        map.put("bindtype", params.getString("bindtype"));
        map.put("status", params.getString("status"));
        map.put("params", entity.getParams());
        Page<TlEquip> listPage = new Page<>(page, size, true);
        IPage<TlEquip> iPage = tlEquipMapper.listEquip(listPage, map);
        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        json.put("equiplist", iPage.getRecords());
        return json;
    }
    @Override
    public void excelReader(List<TlEquip> tlEquipList) throws ExcelReaderDataException {

        String uid = LoginUtils.getUser().getUid();
        String str = "";
        QueryWrapper<TlEquiptype> tlEquiptypeQueryWrapper=new QueryWrapper<>();

        List<TlEquiptype> tlEquiptypeList=tlEquiptypeMapper.selectList(tlEquiptypeQueryWrapper);
        Map<String,TlEquiptype> tlEquiptypeMap=new HashMap<>();

        //EXCEL导入数据重复判断==================================
        List<TlEquip> tlEquipListCheck = tlEquipMapper.selectList(new QueryWrapper<>());

        List<String> code = tlEquipList.stream().map(TlEquip::getEquipcode).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(AttributeUtils.RepeatedList(code))){
            for(Object a :AttributeUtils.RepeatedList(code)){
                str +="'第"+a+"条' 的 “设备编号:"+code.get((int)a-1)+"”  重复;##";
            }
        }
        List<String> name = tlEquipList.stream().map(TlEquip::getEquipname).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(AttributeUtils.RepeatedList(name))){
            for(Object a :AttributeUtils.RepeatedList(name)){
                str +="'第"+a+"条' 的 “设备名称:"+name.get((int)a-1)+"”  重复;##";
            }
        }
        List<String> communicationcode = tlEquipList.stream().map(TlEquip::getCommunicationcode).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(AttributeUtils.RepeatedList(communicationcode))){
            for(Object a :AttributeUtils.RepeatedList(communicationcode)){
                str +="'第"+a+"条' 的 “设备通讯号:"+communicationcode.get((int)a-1)+"”  重复;##";
            }
        }
        //EXCEL导入数据重复判断结束================================

        if(!tlEquiptypeList.isEmpty()){
            Predicate<TlEquiptype> equipTypeNotNull= equipType-> StringUtils.isNotEmpty(equipType.getEquipname());
            tlEquiptypeList=tlEquiptypeList.stream().filter(equipTypeNotNull).collect(Collectors.toList());
            tlEquiptypeMap= GroupingByUtils.getGroupingForMapEntity(tlEquiptypeList,TlEquiptype::getEquipname,Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        int num=1;
        for (TlEquip equip : tlEquipList) {
            equip.setCreatetime(new Date());
            equip.setCreateby(uid);
            //设备参数匹配判断===================================
            if(tlEquiptypeMap.containsKey(equip.getEquiptype())){
                equip.setEquiptypeid(tlEquiptypeMap.get(equip.getEquiptype()).getId());
            }else {
                str +="'第"+num+"条' 的 “设备类型” 不存在;##";
            }
            //设备参数匹配判断结束================================

            //设备判空处理=======================================
            if(StringUtils.isEmpty(equip.getEquipcode())){
                str +="'第"+num+"条' 的 “设备编号” 不能为空;##";
            }
            if(StringUtils.isEmpty(equip.getEquiptype())){
                str +="'第"+num+"条' 的 “设备类型” 不能为空;##";
            }
            if(StringUtils.isEmpty(equip.getEquiptype())){
                str +="'第"+num+"条' 的 “设备通讯号” 不能为空;##";
            }
            //设备判空处理结束=====================================

            //数据库查询判断=======================================
            boolean ck =false;
                for(TlEquip al: tlEquipListCheck){
                    if(StringUtils.isNotEmpty(al.getEquipcode()) && equip.getEquipcode().equals(al.getEquipcode())){
                        str += "'第"+num+"条' 档案中已存在 “设备编号:" + equip.getEquipcode() + "”;";
                        ck = true;
                    }
                    if(StringUtils.isNotEmpty(al.getEquipname()) && equip.getEquipname().equals(al.getEquipname())){
                        if(ck == true){
                            str += "“设备名:"+equip.getEquipname()+"”;";
                        }else{
                            str += "'第"+num+"条' 档案中已存在 “设备名:"+equip.getEquipname()+"”;";
                        }
                        ck = true;
                    }
                    if(StringUtils.isNotEmpty(al.getCommunicationcode()) && equip.getCommunicationcode().equals(al.getCommunicationcode())){
                        if(ck == true){
                            str += "“设备通讯号:"+equip.getCommunicationcode()+"”;";
                        } else{
                            str += "'第"+num+"条' 档案中已存在 “设备通讯号:"+equip.getCommunicationcode()+"”;";
                        }
                        ck = true;
                    }
            }
                if(ck == true){
                    str += "##";
                }
            //数据库查询判断结束=======================================
            num++;
        }
        if(StringUtils.isNotEmpty(str)){
            throw new ExcelReaderDataException("您导入的数据:##"+str);
        }

        }

    @Override
    public Map<String, TlEquip> getTlEquipMap(QueryWrapper<TlEquip> tlEquipQueryWrapper)  {
        List<TlEquip> tlEquipList=tlEquipMapper.selectList(tlEquipQueryWrapper);
        Map<String, TlEquip> tlEquipMap= new HashMap<>();
        if (!tlEquipList.isEmpty()) {
            tlEquipMap = GroupingByUtils.getGroupingForMapEntity(tlEquipList, TlEquip::getId, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        return tlEquipMap;
    }

    @Override
    public Map<String, TlEquip> getTlEquipMapByEquipcodeMap(QueryWrapper<TlEquip> tlEquipQueryWrapper)  {
        List<TlEquip> tlEquipList=tlEquipMapper.selectList(tlEquipQueryWrapper);
        Map<String, TlEquip> tlEquipMap= new HashMap<>();
        if (!tlEquipList.isEmpty()) {
            tlEquipMap = GroupingByUtils.getGroupingForMapEntity(tlEquipList, TlEquip::getEquipcode, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        return tlEquipMap;
    }

    @Override
    public List<TlEquipExcelOutVO> getEquipWithChannel() {
        List<TlEquipExcelOutVO> list = tlEquipMapper.getEquipWithChannel(new HashMap());
        QueryWrapper<TlChannel> tlChannelQueryWrapper = new QueryWrapper<>();
        tlChannelQueryWrapper.lambda().eq(TlChannel::getStatus, "1");
        tlChannelQueryWrapper.lambda().orderByAsc(TlChannel::getChannelname);
        Map<String, List<TlChannel>> tlChannelCollect = tlChannelMapper.selectList(tlChannelQueryWrapper).stream().filter(item -> StringUtils.isNotEmpty(item.getEquipid()))
                .collect(Collectors.groupingBy(TlChannel::getEquipid));
        if(!CollectionUtils.isEmpty(list)){
            for (TlEquipExcelOutVO tlEquipExcelOutVO : list) {
                tlEquipExcelOutVO.setChannels(tlChannelCollect.get(tlEquipExcelOutVO.getId()));
            }
        }
        return list;
    }

    @Override
    public Map<String, TlEquip> getTlEquipMapByBindobjidMap(QueryWrapper<TlEquip> tlEquipQueryWrapper)  {
        List<TlEquip> tlEquipList=tlEquipMapper.selectList(tlEquipQueryWrapper);
        Map<String, TlEquip> tlEquipMap= new HashMap<>();
        if (!tlEquipList.isEmpty()) {
            tlEquipMap = tlEquipList.stream().filter(map->map.getBindobjid() != null).collect(Collectors.groupingBy(TlEquip::getBindobjid, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
        }
        return tlEquipMap;
    }
}
